package com.kxyu.cash_drawer;



import java.io.UnsupportedEncodingException;


public class MacEcbUtils {

	private static final String TAG = "MacEcbUtils";

	public static void main(String[] args) {
	      //new byte[]{0x5C, (byte) 0xBE, 0x7E, 0x38, (byte) 0xA1, 0x46, (byte) 0xFD, 0x5C};
	      //  byte[] input = BytesUtil.hexString2Bytes("12345678901234567890123456789012345678901234567890");//new byte[]{0x01, 0x02, 0x03};
//	      byte[] key = "11111111111111111111111111111111".getBytes();//new byte[]{0x5C, (byte) 0xBE, 0x7E, 0x38, (byte) 0xA1, 0x46, (byte) 0xFD, 0x5C};
//	        System.out.println(new String(key));
	      // byte[] input = "12345678901234567890123456789012345678901234567890".getBytes();
	      // byte[] input = "11111111111111111111111111111111".getBytes();
	      // String result = getMac("11111111111111111111111111111111", "term_version=1.6.0&mchnt_cd=818452058120128&random_str=602d4328c92e4d1eafb115f977d23830&order_amt=1&mchnt_order_no=T2455851420180112112651&txn_begin_ts=20180112112651&auth_code=13457794396685823800002924558514");
	      // System.out.println(result);
	       //byte[] result ="26BE4A67751AE88E".getBytes();//DesUtils.trides_crypt(input, key); //new String(getMac(key, input));
	    //  System.out.println(new String(DesUtils.trides_decrypt(BytesUtil.hexString2Bytes("7C7C3706A218DE6D7C7C3706A218DE6D"), key)));
	       // System.out.println(bytesToHexString(getMac(key, input))
	        String key = "D7A4EFC0FC7A6508171995EA67A41089";//new byte[]{0x5C, (byte) 0xBE, 0x7E, 0x38, (byte) 0xA1, 0x46, (byte) 0xFD, 0x5C};
	        String inputStr="term_version=BZ4.6_BCM&mchnt_cd=0002230F0561752&reserved_fy_term_id=00000012&masterKeySsn=00000303Q4NL00000012";
	        String encodeStr=MacEcbUtils.getMac(key, inputStr);
	        System.out.println(encodeStr);
	    }
	  
	    /** 
	     * mac计算
		 * @param key   mac秘钥
	     * @param Input 待加密数据 
	     * @return 
	     */  
	    public static String getMac(String keyStr, String inputStr) {
	    	byte[] key = BytesUtil.hexString2Bytes(keyStr);
	    	byte[] input = null;//inputStr.getBytes();
	    	try {
				input = inputStr.getBytes("UTF-8");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	        int length = input.length;  
	        int x = length % 8;  
	        // 需要补位的长度  
	        int addLen = 0;  
	        if (x != 0) {  
	            addLen = 8 - length % 8;  
	        }  
	        int pos = 0;  
	        // 原始数据补位后的数据  
	        byte[] data = new byte[length + addLen];  
	        System.arraycopy(input, 0, data, 0, length);  
	        byte[] oper1 = new byte[8];  
	        System.arraycopy(data, pos, oper1, 0, 8);  
	        pos += 8;  
	        // 8字节异或  
	        for (int i = 1; i < data.length / 8; i++) {  
	            byte[] oper2 = new byte[8];  
	            System.arraycopy(data, pos, oper2, 0, 8);  
	            byte[] t = bytesXOR(oper1, oper2);  
	            oper1 = t;  
	            pos += 8;  
	        }  
	        // 将异或运算后的最后8个字节（RESULT BLOCK）转换成16个HEXDECIMAL：  
	        byte[] resultBlock = bytesToHexString(oper1).getBytes();  
	        // 取前8个字节MAK加密  
	        byte[] front8 = new byte[8];  
	        System.arraycopy(resultBlock, 0, front8, 0, 8);  
	       // System.out.println("---------------------------front8--->"+new String(front8));
	        byte[] behind8 = new byte[8];  
	        System.arraycopy(resultBlock, 8, behind8, 0, 8);  
	      //  System.out.println("---------------------------behind8--->"+new String(behind8));
	        byte[] desfront8 = DesUtils.trides_crypt(front8, key);  
	      //  System.out.println("---------------------------desfront8--->"+new String(bytesToHexString(desfront8)));
	        // 将加密后的结果与后8 个字节异或：  
	        byte[] resultXOR = bytesXOR(desfront8, behind8);  
	    //    System.out.println("---------------------------resultXOR--->"+new String(bytesToHexString(resultXOR)));
	        // 用异或的结果TEMP BLOCK 再进行一次单倍长密钥算法运算  
	        byte[] buff = DesUtils.trides_crypt(resultXOR, key);  
	        // 将运算后的结果（ENC BLOCK2）转换成16 个HEXDECIMAL asc  
	       // byte[] retBuf = new byte[8];  
	       // System.out.println(bytesToHexString(buff));
	        // 取8个长度字节就是mac值  
	      //  System.arraycopy(bytesToHexString(buff).getBytes(), 0, retBuf, 0, 8);  
	        return new String(bytesToHexString(buff));  
	    }  
	  
	    
	    public static String getMac(String keyStr, String inputStr, String charType) {
	    	byte[] key = BytesUtil.hexString2Bytes(keyStr);
	    	byte[] input = null;
			try {
				input = inputStr.getBytes(charType);
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	        int length = input.length;  
	        int x = length % 8;  
	        // 需要补位的长度  
	        int addLen = 0;  
	        if (x != 0) {  
	            addLen = 8 - length % 8;  
	        }  
	        int pos = 0;  
	        // 原始数据补位后的数据  
	        byte[] data = new byte[length + addLen];  
	        System.arraycopy(input, 0, data, 0, length);  
	        byte[] oper1 = new byte[8];  
	        System.arraycopy(data, pos, oper1, 0, 8);  
	        pos += 8;  
	        // 8字节异或  
	        for (int i = 1; i < data.length / 8; i++) {  
	            byte[] oper2 = new byte[8];  
	            System.arraycopy(data, pos, oper2, 0, 8);  
	            byte[] t = bytesXOR(oper1, oper2);  
	            oper1 = t;  
	            pos += 8;  
	        }  
	        // 将异或运算后的最后8个字节（RESULT BLOCK）转换成16个HEXDECIMAL：  
	        byte[] resultBlock = bytesToHexString(oper1).getBytes();  
	        // 取前8个字节MAK加密  
	        byte[] front8 = new byte[8];  
	        System.arraycopy(resultBlock, 0, front8, 0, 8);  
	       // System.out.println("---------------------------front8--->"+new String(front8));
	        byte[] behind8 = new byte[8];  
	        System.arraycopy(resultBlock, 8, behind8, 0, 8);  
	      //  System.out.println("---------------------------behind8--->"+new String(behind8));
	        byte[] desfront8 = DesUtils.trides_crypt(front8, key);  
	      //  System.out.println("---------------------------desfront8--->"+new String(bytesToHexString(desfront8)));
	        // 将加密后的结果与后8 个字节异或：  
	        byte[] resultXOR = bytesXOR(desfront8, behind8);  
	    //    System.out.println("---------------------------resultXOR--->"+new String(bytesToHexString(resultXOR)));
	        // 用异或的结果TEMP BLOCK 再进行一次单倍长密钥算法运算  
	        byte[] buff = DesUtils.trides_crypt(resultXOR, key);  
	        // 将运算后的结果（ENC BLOCK2）转换成16 个HEXDECIMAL asc  
	       // byte[] retBuf = new byte[8];  
	       // System.out.println(bytesToHexString(buff));
	        // 取8个长度字节就是mac值  
	      //  System.arraycopy(bytesToHexString(buff).getBytes(), 0, retBuf, 0, 8);  
	        return new String(bytesToHexString(buff));  
	    }
	    
	    /** 
	     * 单字节异或
	     * @param src1 
	     * @param src2 
	     * @return 
	     */  
	    public static byte byteXOR(byte src1, byte src2) {  
	        return (byte) ((src1 & 0xFF) ^ (src2 & 0xFF));  
	    }  
	  
	    /** 
	     * 字节数组异或
	     * @param src1 
	     * @param src2 
	     * @return 
	     */  
	    public static byte[] bytesXOR(byte[] src1, byte[] src2) {  
	        int length = src1.length;  
	        if (length != src2.length) {  
	            return null;  
	        }  
	        byte[] result = new byte[length];  
	        for (int i = 0; i < length; i++) {  
	            result[i] = byteXOR(src1[i], src2[i]);  
	        }  
	        return result;  
	    }  
	  
	    /** 
	     * 字节数组转HEXDECIMAL
	     * @param bArray 
	     * @return 
	     */  
	    public static final String bytesToHexString(byte[] bArray) {  
	        StringBuffer sb = new StringBuffer(bArray.length);  
	        String sTemp;  
	        for (int i = 0; i < bArray.length; i++) {  
	            sTemp = Integer.toHexString(0xFF & bArray[i]);  
	            if (sTemp.length() < 2)  
	                sb.append(0);  
	            sb.append(sTemp.toUpperCase());  
	        }  
	        return sb.toString();  
	    }  
	}  